Categories
Gatsby.js

Gatsby.js — Custom RSS Feed

Spread the love

Gatsby is a static web site framework that’s based on React.

We can use it to create static websites from external data sources and more.

In this article, we’ll look at how to create a site with Gatsby.

Customize RSS Feed

We can customize our RSS feed by adding more plugin options into gatsby-config.js.

For example, we can write:

gatsby-config.js

module.exports = {
  plugins: [
    `gatsby-transformer-remark`,
    {
      resolve: `gatsby-plugin-feed`,
      options: {
        query: `
          {
            site {
              siteMetadata {
                title
                description
                siteUrl
                site_url: siteUrl
              }
            }
          }
        `,
        feeds: [
          {
            serialize: ({ query: { site, allMarkdownRemark } }) => {
              return allMarkdownRemark.edges.map(edge => {
                return Object.assign({}, edge.node.frontmatter, {
                  description: edge.node.excerpt,
                  date: edge.node.frontmatter.date,
                  url: site.siteMetadata.siteUrl + edge.node.fields.slug,
                  guid: site.siteMetadata.siteUrl + edge.node.fields.slug,
                  custom_elements: [{ "content:encoded": edge.node.html }],
                })
              })
            },
            query: `
              {
                allMarkdownRemark(
                  sort: { order: DESC, fields: [frontmatter___date] },
                ) {
                  edges {
                    node {
                      excerpt
                      html
                      fields { slug }
                      frontmatter {
                        title
                        date
                      }
                    }
                  }
                }
              }
            `,
            output: "/rss.xml",
            title: "Your Site's RSS Feed",
          },
        ],
      },
    },
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `content`,
        path: `${__dirname}/src/content`,
      },
    },
  ],
  siteMetadata: {
    siteUrl: `https://www.example.com`,
  },
}

We need siteMetadata.siteUrl to generate the RSS feed.

gatsby-node.js

const path = require("path")
const _ = require("lodash")
const { createFilePath } = require(`gatsby-source-filesystem`)

exports.onCreateNode = ({ node, actions, getNode }) => {
  const { createNodeField } = actions
  if (node.internal.type === `MarkdownRemark`) {
    const value = createFilePath({ node, getNode })
    createNodeField({
      name: `slug`,
      node,
      value,
    })
  }
}

exports.createPages = async ({ actions, graphql, reporter }) => {
  const { createPage } = actions
  const blogPostTemplate = path.resolve("src/templates/post.js")
  const result = await graphql(`
    {
      postsRemark: allMarkdownRemark(
        sort: { order: DESC, fields: [frontmatter___date] }
        limit: 2000
      ) {
        edges {
          node {
            fields {
              slug
            }
            frontmatter {
              tags
            }
          }
        }
      }
      tagsGroup: allMarkdownRemark(limit: 2000) {
        group(field: frontmatter___tags) {
          fieldValue
        }
      }
    }
  `)
  if (result.errors) {
    reporter.panicOnBuild(`Error while running GraphQL query.`)
    return
  }
  const posts = result.data.postsRemark.edges
  posts.forEach(({ node }) => {
    const slug = node.fields.slug
    createPage({
      path: slug,
      component: blogPostTemplate,
      context: { slug },
    })
  })
}

src/templates/post.js

import React from "react"
import { graphql } from "gatsby"

export default function BlogPost({ data }) {
  const post = data.markdownRemark
  return (
    <div>
      <h1>{post.frontmatter.title}</h1>
      <div dangerouslySetInnerHTML={{ __html: post.html }} />
    </div>
  )
}
export const query = graphql`
  query($slug: String!) {
    markdownRemark(fields: { slug: { eq: $slug } }) {
      html
      frontmatter {
        title
      }
    }
  }
`

We add the gatsby-plugin-feed plugin into gatsby-config.js .

We install the plugin by running:

npm i gatsby-plugin-feed

We add some options into our config file. The options.query property has the string for the GraphQL query to get the site’s metadata.

The feeds property has the serialize method to get the data from the query and return an object for each entry that’s retrieved.

description has the description of the post.

date has the date of the post.

url has the URL of the post.

guid is a unique ID we generate.

custom_elements have extra elements that we want to include in the RSS feed.

feeds.query has the query to get the posts.

output has the path for the RSS feed file.

title has the feed’s title.

In gatsby-node.js , we make the GraphQL query to get the Markdown posts and call createPage to create the posts.

And post.js displays the post by getting the data from the data prop.

Now when we run npm run build , we see the public/rss.xml file generated.

We should see the item element with the title , description , link , guid , pubDate , and content:encoded elements.

Conclusion

We can create a custom RSS feed for our site with Gatsby.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *